package cluster

import (
	"encoding/json"
	"errors"
	"gitee.com/cooge/impush/cluster/conn"
	"gitee.com/cooge/impush/core"
	"gitee.com/cooge/impush/message"
	"github.com/sirupsen/logrus"
	"net"
	"strconv"
	"strings"
)

type ClusterServer struct {
	*net.TCPListener
}

func NewClusterServer() *ClusterServer {
	var cs ClusterServer
	return &cs
}
func (cs *ClusterServer) Bind(lport int) error {
	listener, err := net.ListenTCP("tcp4", &net.TCPAddr{
		IP:   net.IPv4(0, 0, 0, 0),
		Port: lport,
	})
	if err == nil {
		core.AddInfo("CLUSTER_LOCAL_PORT", lport)
		cs.TCPListener = listener
	}
	return err
}
func (cs *ClusterServer) Accept() (*conn.ClusterConn, error) {
	if cs.TCPListener != nil {
		tcn, err := cs.TCPListener.Accept()
		if err == nil {
			nt, ok := tcn.(*net.TCPConn)
			if ok {
				return conn.NewClusterConn(nt, cs.ClusterHandleFunc), nil
			} else {
				return nil, errors.New("CLUSTER TCP ERROR")
			}
		} else {
			return nil, err
		}
	}
	return nil, errors.New("SYS CLUSTER TCP ERROR")
}
func (cs *ClusterServer) ClusterHandleFunc(clusterConn *conn.ClusterConn, msg *message.Message, code int) {

	switch code {

	case conn.ADD_MACHINE:
		{

			bb := string(msg.Body)
			if len(bb) > 0 {
				addess := strings.Split(bb, ";")
				for _, v := range addess {
					ads := strings.Split(v, ":")
					if len(ads) == 2 {
						host := ads[0]
						port, err := strconv.Atoi(ads[1])
						if err == nil {
							startClient(host, port)
						}
					}
				}
			}
		}
	case conn.ADD_USER:
		{
			data := msg.Body
			if len(data) > 0 {
				var cus []*clusterUser
				err := json.Unmarshal(data, &cus)
				if err == nil {
					for _, v := range cus {
						if clusterConn.Close{
							break
						}
						ncc := NewClusterConnUser(clusterConn.UserTCPConn, clusterConn.LiveTime, v)
						if ncc != nil {
							addClusterUser(ncc.UserId, ncc)
						}

					}
				}
			}
		}
	case conn.DELETE_MACHINE:
		{
			deleteClusterConnUser(clusterConn)
		}

	case conn.DELETE_USER:
		{

			data := msg.Body
			if len(data) > 0 {
				var cus []*clusterUser
				err := json.Unmarshal(data, &cus)
				if err == nil {
					for _, v := range cus {
						ncc := NewClusterConnUser(clusterConn.UserTCPConn, clusterConn.LiveTime, v)
						if ncc != nil {
							deleteClusterUser(ncc.UserId, ncc)
						}
					}
				} else {
					logrus.Debug("批量用户发送转换失败", err)
				}
			}

		}

	}

}
